# This software is Free Software ( Free as in Freedom ). And it's (c) J.Y.Amihud and
# other contributors 2022. Under the terms of GNU General Public License Version 3 or
# any later version as published by the Free Software Foundation.

import os
import time
import random
import threading
import subprocess
import json
from gi.repository import GLib

from modules import youtube

def difference(x,y):
    if x > y:
        return x - y
    else:
        return y - x

def playsong(win):

    load_playlist(win)

    if not win.playlist:
        load_reserve(win)
        win.playlist.append(choose_random(win))
        save_playlist(win)
    
    played = False
    for i in win.playlist:
        if i.get("file") != None and win.keep_playing:
            print("Playing", i.get("title"))
            win.playing_now = i
            win.mpv = subprocess.Popen(["mpv", i.get("file"), "--no-video", "--audio-channels=mono", "--af=lavfi=dynaudnorm"])
            win.playindex += 1
            if "picture" in i:
                GLib.idle_add(win.change_preview, True,  i["picture"],i["title"])
                #win.change_preview(True, i["picture"],i["title"])
            played = True
            break
        
    if not played and win.keep_playing:
        try:
            print("Trying reserve song")
            load_reserve(win)
            print(1)
            i = choose_random(win)
            print(2)
            win.playing_now = i
            print(3)
            win.mpv = subprocess.Popen(["mpv", i.get("file"), "--no-video", "--audio-channels=mono", "--af=lavfi=dynaudnorm"])
            print(4)
            if "picture" in i:
                print(5)
                GLib.idle_add(win.change_preview, True,  i["picture"],i["title"])
                print(6)
                #win.change_preview(True, i["picture"],i["title"])
        except Exception as e:
            print("second error", e)
            pass
        
    def wait(win):
        win.mpv.wait()
        load_playlist(win)
        try:
            win.playlist.remove(win.playing_now)
            
            # Deleting the file after playing it
            if win.playing_now not in win.reserve_playlist:
                os.remove(win.playing_now["file"])
                
                
        except:
            pass
        save_playlist(win)

        time.sleep(1)
        if win.keep_playing:
            playsong(win)
    waitt = threading.Thread(target=wait, args=(win,))
    waitt.start()
    
    while win.keep_playing:
        pass
    
    win.mpv.kill()

def load_playlist(win):
    with open('playlist_request.json') as json_file: 
        win.playlist = json.load(json_file)

def load_reserve(win):
    with open('reserve_list.json') as json_file: 
        win.reserve_playlist = json.load(json_file)

def save_playlist(win):
    with open('playlist_request.json', 'w') as fp:
        json.dump(win.playlist, fp, indent=4)

def add_song(win, song):
    
    load_playlist(win)
    win.playlist.append(song)
    save_playlist(win)

    if song["file"] == None and "videoId" in song:
        # Downloading the song
        def downloadthread(win, song):
            print("Downloading...")
            if youtube.insure_song(song["videoId"], song["videoId"]):
                print("Down!")
                load_playlist(win)
                for i in win.playlist:
                    if i.get("videoId") == song["videoId"]:
                        print("Found matching ID")
                        for b in os.listdir("downloads"):
                            if b.startswith(song["videoId"]):
                                print("Found the file")
                                i["file"] = "downloads/"+b
                print("Saving...")
                save_playlist(win)
                print("Done!")
        dthread = threading.Thread(target=downloadthread, args=(win, song))
        dthread.start()
                
def choose_random(win):

    load_reserve(win)
    chosen_song = random.choice(win.reserve_playlist)
    index = win.reserve_playlist.index(chosen_song)

    loop = 1000
    while difference(index, win.chosen[-1]) < 40 or index in win.chosen:
        loop -= 1
        chosen_song = random.choice(win.reserve_playlist)
        index = win.reserve_playlist.index(chosen_song)

        if loop < 1:
            break
    win.chosen.append(index)
    return chosen_song
    
